﻿using H.Daos;
using H.Daos.Attributes;
using H.Utils;
using System;
using System.Collections.Generic;
using System.Reflection;

namespace H.Dao.SQLite.Daos.Cache
{
    internal static class ModelMapping<M> where M : AbstractEntity
    {
        /// <summary>
        /// 模型对应的数据库表名
        /// </summary>
        public static readonly string TableName;

        /// <summary>
        /// 模型的主键
        /// </summary>
        public static readonly string PrimaryKey;

        /// <summary>
        /// 模型字段映射
        /// </summary>
        public static readonly Dictionary<string, FieldMapping> ColumnDict = new Dictionary<string, FieldMapping>();

        /// <summary>
        /// 模型字段列表
        /// </summary>
        public static readonly List<FieldMapping> ColumnList = new List<FieldMapping>();

        /// <summary>
        /// 模型字段名字符串
        /// </summary>
        public static readonly string ColumnNames;

        /// <summary>
        /// 模型字段占位符
        /// </summary>
        public static readonly string ColumnPlaceHolder;

        /// <summary>
        /// 初始化一个模型映射
        /// </summary>
        static ModelMapping()
        {
            Type type = typeof(M);
            object[] attrs;

            #region 获取模型对应的表名
            attrs = type.GetCustomAttributes(typeof(TableAttribute), true);
            if (attrs.Length > 0)
            {
                TableName = (attrs[0] as TableAttribute).TableName;
            }
            else
            {
                TableName = type.Name.ToUnderScoreCase();
            }
            #endregion

            #region 获取模型字段名
            PropertyInfo[] props = type.GetProperties();
            string pkField = null;

            List<string> fields = new List<string>();
            foreach (PropertyInfo prop in props)
            {
                FieldMapping field = FieldMapping.GetInstance(prop);
                if (field != null)
                {
                    ColumnDict.Add(prop.Name, field);
                    ColumnList.Add(field);
                    fields.Add(field.ColumnName);

                    if (field.IsPrimaryKey)
                    {
                        pkField = field.ColumnName;
                    }
                }
            }
            ColumnNames = string.Join(",", fields);
            ColumnPlaceHolder = "@" + string.Join(",@", fields);

            if (pkField != null)
            {
                PrimaryKey = pkField;
            }
            else
            {
                throw new Exception("必须为模型指定主键");
            }

            #endregion
        }

    }
}
